package com.lzw.blog.Service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;

import com.lzw.blog.dao.mapper.ArticleMapper;
import com.lzw.blog.dao.pojo.Article;

import com.lzw.blog.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.Set;

@Slf4j
@Service
public class ThreadService {
    @Autowired
    private StringRedisTemplate redisTemplate;
    //此操作在线程池中进行操作,执行,不会影响所有主线程
    //异步任务
    /**
     * 这段代码主要是用于更新文章的浏览量（viewCounts）。
     * 首先，通过 article.getViewCounts() 获取当前文章的浏览量，并将其存储在 viewCounts 变量中。
     * 接着，创建一个新的 Article 对象 articleUpdate，并将其浏览量设置为 viewCounts+1。
     * 然后，创建一个 LambdaUpdateWrapper<Article> 对象 updateWrapper，用于构建更新文章的条件。通过 updateWrapper.eq(Article::getId,article.getId())
     * 指定更新条件为文章的 id 值等于当前文章的 id 值。
     * 为了保证多线程环境下的线程安全，使用 updateWrapper.eq(Article::getViewCounts,viewCounts) 指定条件为浏览量值等于 viewCounts。
     * 最后，调用 articleMapper.update(articleUpdate,updateWrapper) 方法来执行更新操作。
     * 该方法将根据指定的条件更新文章表中满足条件的文章的浏览量为 viewCounts+1。类似于 SQL 语句：update article set view_count=100 where view_count=99 and id=11。
     */
    @Async("taskExecutor")
    public void updateArticleViewCount(ArticleMapper articleMapper, Article article) {
        int viewCounts = article.getViewCounts();
        Article articleUpdate = new Article();
        articleUpdate.setViewCounts(viewCounts+1);
        LambdaUpdateWrapper<Article> updateWrapper=new LambdaUpdateWrapper<>();
        updateWrapper.eq(Article::getId,article.getId());
        //设置一个为了在多线程的环境下线程安全
        updateWrapper.eq(Article::getViewCounts,viewCounts);
        //update article set view_count=100 where view_count=99 and id=11
        articleMapper.update(articleUpdate,updateWrapper);
    }

    @Async("taskExecutor")
    public void updateArticle(Article article) {

        //做什么了，更新缓存
        //1. 更新查看文章详情的缓存
        Long articleId = article.getId();
        String params = DigestUtils.md5Hex(articleId.toString());
        String redisKey = "view_article::ArticleController::findArticleById::"+params;
        Result articleResult =  new Result();
        articleResult.setData(article);
        redisTemplate.opsForValue().set(redisKey, JSON.toJSONString(articleResult), Duration.ofMillis(5 * 60 * 1000));
        log.info("更新了缓存:{}",redisKey);

        //2. 文章列表的缓存 不知道参数,解决办法 直接删除缓存
        Set<String> keys = redisTemplate.keys("listArticle*");
        keys.forEach(s -> {
            redisTemplate.delete(s);
            log.info("删除了文章列表的缓存:{}",s);
        });
    }


}
